--common functions used by gcommunicate
gcommunicate.lib = {}

--just a placeholder function for UPDATE and INSERT threaded queries.
function gcommunicate.lib.generalthreadcallback(query)

end

--updates the timestamp var gcommunicate.lastcheck
function gcommunicate.lib.updatelastcheck(query)
	gcommunicate.lastcheck = query[1][1]
end

--calls an update to the maxid
function gcommunicate.lib.getmaxid()
	gdatabase.threadedquery("SELECT MAX(id) FROM chat", gcommunicate.DB, gcommunicate.lib.getmaxidthread)
end


function gcommunicate.lib.getmaxidthread(query)
	gcommunicate.maxid = query[1][1]
end

--This function runs whenever the database comes online, inits/reinits the settings
function gcommunicate.lib.connectinit()
	local sname = gdatabase.CleanString(gcommunicate.DB, gcommunicate.config.servername)
	--get the server id
	local query = gdatabase.Query("SELECT id from `servers` WHERE name=\'"..sname.."\';", gcommunicate.DB)
	
	if type(query[1]) == "nil" then 
		local config = gcommunicate.config
		local query2 = gdatabase.Query("INSERT INTO servers (ip, name, port, lastchecked) VALUES (\""  .. config["serverip"] .. "\", \"" .. config["servername"] .."\", " .. config["serverport"] .. ", UNIX_TIMESTAMP());", gcommunicate.DB)
		query2 = gdatabase.Query("SELECT id from `servers` WHERE name=\'"..sname.."\';", gcommunicate.DB)
		gcommunicate.serverid = query2[1][1] or 0
	else
		gcommunicate.serverid = query[1][1] or 0
	end
	--set the server to online
	local query = gdatabase.Query("UPDATE `servers` SET isonline=\'1\' WHERE name=\'"..sname.."\';", gcommunicate.DB)
	
	--Ok were going to flush all the players that were connected to our server in case of a unexpected crash
	local query = gdatabase.Query("UPDATE `clients` SET isonline=\'0\' WHERE serverid=\'"..gcommunicate.serverid.."\';", gcommunicate.DB)
	
	--check for players on server and update the database if required
	for k, ply in pairs(player.GetAll()) do
		gcommunicate.PlayerInitialSpawn(ply)
	end 
	
	
	
	--announce the server coming up
	gdatabase.Query("INSERT INTO `chat` ( `serverid` , `playerid` , `pname`, `time` , `chat` ) VALUES ( \'"..gcommunicate.serverid.."\', \'0\', \'Console\', UNIX_TIMESTAMP() , \'"..sname.." has come online.\' );", gcommunicate.DB)
	
	--gcommunicate.lastcheck = gdatabase.Query("SELECT UNIX_TIMESTAMP() FROM `chat` LIMIT 1;", gcommunicate.DB)[1][1]
	gcommunicate.maxid = gdatabase.Query("SELECT MAX(id) FROM chat", gcommunicate.DB)[1][1]
	

	--Add the hooks
	hook.Add("PlayerInitialSpawn", "gcommunicatePlayerInitalSpawn", gcommunicate.PlayerInitialSpawn)
	hook.Add("PlayerDisconnected", "gcommunicatePlayerDisconnected", gcommunicate.PlayerDisconnected)
	hook.Add("PlayerSay", "gcommunicatePlayerSay", gcommunicate.PlayerSay)
	
	--timer
	timer.UnPause("gcommunicateMessages")
	timer.UnPause("gcommunicatePurgeChecker")
end

function gcommunicate.lib.disconnectinit()
	Msg("GCOMMUNICATE: Connection lost, Removing Hooks\n")
	
	--Hook Removes
	hook.Remove("PlayerInitialSpawn", "gcommunicatePlayerInitalSpawn")
	hook.Remove("PlayerDisconnected", "gcommunicatePlayerDisconnected")
	hook.Remove("PlayerSay", "gcommunicatePlayerSay")
	
	--Pause the timer
	timer.Pause("gcommunicateMessages")
	timer.Pause("gcommunicatePurgeChecker")
end

function gcommunicate.lib.reinit()
	timer.Remove("gcommunicateMessages")
	timer.Remove("gcommunicatePurgeChecker")
	gdatabase.HookRemove("connect", "gcommunicate_connect", gcommunicate.DB)
	gdatabase.HookRemove("disconnect", "gcommunicate_disconnect", gcommunicate.DB)
	gdatabase.HookRemove("shutdown", "gcommunicate_shutdown", gcommunicate.DB)
	gdatabase.KillConnection(gcommunicate.DB)
	gcommunicate.Initialize()
	timer.Create("gcommunicateMessages",gcommunicate.config.updatetime,0,gcommunicate.Messages)
	timer.Create("gcommunicatePurgeChecker", 3600, 0, gcommunicate.lib.purgecheck)
end
concommand.Add("gcomm_reload", gcommunicate.lib.reinit)

function gcommunicate.lib.shutdown()
	Msg("GCOMMUNICATE SHUTTING DOWN!\n")
	local sname = gdatabase.CleanString(gcommunicate.DB, gcommunicate.config.servername)
	local query = gdatabase.Query("UPDATE `servers` SET isonline=\'0\' WHERE name=\'"..sname.."\';", gcommunicate.DB)
end

function gcommunicate.lib.purgecheck()
	gdatabase.threadedquery("SELECT COUNT(*) FROM chat;", gcommunicate.DB, gcommunicate.lib.purgecheck2)
end

function gcommunicate.lib.purgecheck2(query)
	local theQuery = tonumber(query[1][1])	
	if theQuery > 100000 then --database is getting too large
		gdatabase.threadedquery("SELECT MAX(id) FROM chat;", gcommunicate.DB, gcommunicate.lib.purgecheck3)
	end	
end

function gcommunicate.lib.purgecheck3(query)
	theQuery = tonumber(query[1][1])
	
	Msg("GCOMMUNICATE: Database getting to large, purging old entries\n")
	gdatabase.threadedquery("DELETE FROM chat WHERE id < " .. tostring(theQuery - 100) .. ";", gcommunicate.DB, gcommunicate.lib.generalthreadcallback)
	--This next line takes care of the database getting unoptimized because of the mass deletes.
	gdatabase.threadedquery("OPTIMIZE TABLE `chat`;", gcommunicate.DB, gcommunicate.lib.generalthreadcallback)
end
timer.Create("gcommunicatePurgeChecker", 3600, 0, gcommunicate.lib.purgecheck)
